//
//  SampleServerAppAppDelegate.m
//  SampleServerApp
//
//  Created by Eberhard Rensch on 04.10.08.
//  Copyright E.R.S 2008. All rights reserved.
//
// Plugin for iMedia Browser
//
// iMedia Browser is based on code originally developed by Jason Terhorst,
// further developed for Sandvox by Greg Hulands, Dan Wood, and Terrence Talbot.
// Contributions have also been made by Matt Gough, Martin Wennerberg and others
// as indicated in source files.
// 
// The iMedia Browser Framework is licensed under the following terms:
// 
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in all or substantial portions of the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the following
// conditions:
// 
//	Redistributions of source code must retain the original terms stated here,
//	including this list of conditions, the disclaimer noted below, and the
//	following copyright notice: Copyright (c) 2008 by Pleasant Software
// 
//	Redistributions in binary form must include, in an end-user-visible manner,
//	e.g., About window, Acknowledgments window, or similar, the original
//	terms stated here, including this list of conditions, the disclaimer noted
//	below, and the aforementioned copyright notice.
// 
//	Neither the name of Pleasant Software, nor the names of
//	contributors to iMedia Browser may be used to endorse or promote products
//	derived from the Software without prior and express written permission from
//	Pleasant Software or individual contributors, as appropriate.
// 
// Disclaimer: THE SOFTWARE IS PROVIDED BY THE COPYRIGHT OWNER AND CONTRIBUTORS
// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
// AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF
// CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH, THE
// SOFTWARE OR THE USE OF, OR OTHER DEALINGS IN, THE SOFTWARE.
//

#import "SampleServerAppAppDelegate.h"
#import "SampleServerAppViewController.h"
#import "NetworkStatusViewController.h"

@interface SampleServerAppAppDelegate (Private)
- (void)refreshFileNameCache;
@end

@implementation SampleServerAppAppDelegate

@synthesize window;
@synthesize mainViewController;
@synthesize fileNameCache;
@synthesize bonjourService;

- (void)applicationDidFinishLaunching:(UIApplication *)application {    
    
	// Override point for customization after app launch
	NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
	docsDirectoryPath = [[paths lastObject] copy];

	fileNameCache=[NSMutableArray new];
	[self refreshFileNameCache];

	[window addSubview:mainViewController.view];
	[window makeKeyAndVisible];

	bonjourService = [[iMBiPhoneViewServer alloc] init];
	[bonjourService setApplicationIdentifier:[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleIdentifier"]];
	bonjourService.serviceIdentifier = @"imediasample"; // Must match with client app!
	bonjourService.delegate = self;
	[bonjourService openConnectionWithTimeOut:30.]; // Publish this service for 30 seconds
}


- (void)dealloc
{
	[docsDirectoryPath release];
	[fileNameCache release];
	[mainViewController release];
	[window release];
	[super dealloc];
}

- (void)applicationWillTerminate:(UIApplication *)application
{
	[self disconnectNetworkConnections];
}


- (void)refreshFileNameCache
{
	[fileNameCache removeAllObjects];
	[fileNameCache addObjectsFromArray:[[NSFileManager defaultManager] directoryContentsAtPath:docsDirectoryPath]];
}

- (void)disconnectNetworkConnections
{
	if(self.bonjourService)
	{
		[self.bonjourService closeConnection];
		self.bonjourService=nil;
	}
	if(networkViewController)
	{
		[UIView beginAnimations:@"flipFromNetworkStatus" context:nil];
		[UIView setAnimationDuration:.75];
		[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:window cache:YES];
		[networkViewController.view removeFromSuperview];
		[window addSubview:mainViewController.view];
		[UIView  commitAnimations];
		
		[networkViewController release];
		networkViewController=nil;
	}
	if(currentUpload)
	{
		[[NSFileManager defaultManager] removeItemAtPath:currentUpload error:nil];
		[currentUpload release];
		currentUpload=nil;
	}
}

#pragma mark iMBiPhoneViewServer delegate functions
- (void)iMBiPhoneViewServerConnectedTo:(NSString*)clientDisplayName;
{
	if(networkViewController == nil)
	{
		networkViewController = [NetworkStatusViewController new];

		[UIView beginAnimations:@"flipToNetworkStatus" context:nil];
		[UIView setAnimationDuration:.75];
		[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:window cache:YES];
		[mainViewController.view removeFromSuperview];
		[window addSubview:networkViewController.view];
		[UIView  commitAnimations];
	}
	if(clientDisplayName)
		[networkViewController setConnectionName:clientDisplayName];
}

- (void)iMBiPhoneViewServerAuthenticate:(NSString*)authenticationCode;
{
	if(authenticationCode)
		[networkViewController promptForAuthCode:authenticationCode];
	else
		[networkViewController.activity startAnimating];
}

- (void)iMBiPhoneViewServerDisconnect
{
	[self disconnectNetworkConnections];
}

- (void)iMBiPhoneViewServerError:(NSError*)error;
{
	NSString* message = [error localizedFailureReason];
	if(message==nil)
		message = NSLocalizedString(@"Unknown error", @"");
	[networkViewController setConnectionName:message];
	
	if(currentUpload)
	{
		[[NSFileManager defaultManager] removeItemAtPath:currentUpload error:nil];
		[currentUpload release];
		currentUpload=nil;
	}
}

- (NSArray*)iMBiPhoneViewServerCatalog;
{
	// Create a content array which is valid for "iMBiPhoneParser::fillLibraryNode:whithContent:"
	
	NSMutableArray* textContent = [NSMutableArray array];
	NSMutableArray* binContent = [NSMutableArray array];
	for(NSString* fileName in self.fileNameCache)
	{
		if([[fileName pathExtension] isEqualToString:@"txt"])
		{
			// In this sample app, all text files are transfered embedded in the catalog.
			// When dragging such entries out of an iMBiPhoneView, the embedded data will be part of the
			// iMBNativePasteboardFlavor (so 3rd party drop targets could extract the data from this),
			// but there won't be any NSFilesPromisePboardType for such entries.
			// Of course, it's possible to combine @"embeddedData" and @"promissedFile" in one entry!
			// To test a embedded data entrie, drag it to the "embedded data tester" drop zone in the SampleClientApp
			
			NSData* fileContent = [NSData dataWithContentsOfFile:[docsDirectoryPath stringByAppendingPathComponent:fileName]];
			if(fileContent)
			{
				NSDictionary* contentRecord = [NSDictionary dictionaryWithObjectsAndKeys:
					fileName, @"displayName",
					fileName, @"uuid", // In this sample the filename itself is the uuid
					fileContent, @"embeddedData",
					// Use the parent's icon for each entry:
					[NSNumber numberWithBool:YES], @"useParentIcon", 
					// Other possible keys/values instead:
					// @"iconData" -> NSData with image data for this entry
					// or "nothing" for no icon at all
					nil];
				[textContent addObject:contentRecord];
			}
		}
		else
		{
			// For all other files, use "promissedFile" for transfer, i.e. transfer the file's content only on request
			NSDictionary* contentRecord = [NSDictionary dictionaryWithObjectsAndKeys:
				fileName, @"displayName",
				fileName, @"uuid", // In this sample the filename itself is the uuid
				[docsDirectoryPath stringByAppendingPathComponent:fileName], @"promissedFile",
				// Use the parent's icon for each entry:
				[NSNumber numberWithBool:YES], @"useParentIcon", 
				// Other possible keys/values instead:
				// @"iconData" -> NSData with image data for this entry
				// or "nothing" for no icon at all
				nil];
			[binContent addObject:contentRecord];
		}
	}
				
	
	NSMutableArray* content = [NSMutableArray array];
	if([textContent count]>0)
	{
		NSData* textIcon = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"textIcon" ofType:@"gif"]];
		[content addObject:[NSDictionary dictionaryWithObjectsAndKeys:
				NSLocalizedString(@"Text",@""), @"displayName",
				@"__textFiles", @"uuid",
				textIcon, @"iconData",
				textContent, @"content",
				nil]];
	}
	if([binContent count]>0)
	{
		NSData* binIcon = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"binIcon" ofType:@"gif"]];
		[content addObject:[NSDictionary dictionaryWithObjectsAndKeys:
				NSLocalizedString(@"Other",@""), @"displayName",
				@"__binFiles", @"uuid",
				binIcon, @"iconData",
				binContent, @"content",
				nil]];
	}
	
	return content;
}

- (id)iMBiPhoneViewServerFetchFileForUUID:(NSString*)uuid;
{	
	// For demo purposes, if a requested file is a rtf-File, it's content is transferred as a pre-loaded NSData object.
	// This type of transfer is intended for small amounts of data (since all data has to be loaded into memory at once)
	// and for "non-file" data (e.g. data fetched from a SQLLite database).

	id data=nil;
	
	// In this sample the filename itself is the uuid.
	if([[uuid pathExtension] isEqualToString:@"rtf"]) // rtf-Files are transferred as pre-loaded NSData object
		data = [NSData dataWithContentsOfFile:[docsDirectoryPath stringByAppendingPathComponent:uuid]];
	else	// all other files are transfered as usual files, just return a NSString with the file path:
		data = [docsDirectoryPath stringByAppendingPathComponent:uuid];
	return data;
}

- (id)iMBiPhoneViewServerSendData:(NSString*)uuid
{
	return nil;
}

- (NSDictionary*)iMBiPhoneViewServerReceivedDataFromComputer:(NSDictionary*)received
{
	return nil;
}

- (NSDictionary*)iMBiPhoneViewServerReceiveFileFromComputerStart:(NSDictionary*)received
{
	NSDictionary* result = nil;
	
	currentUpload = [[docsDirectoryPath stringByAppendingPathComponent:[received objectForKey:@"fileName"]] retain];
	BOOL overwrite = [[received objectForKey:@"overwrite"] boolValue];
	
	NSFileManager* fm = [NSFileManager defaultManager];
	if(![fm fileExistsAtPath:currentUpload])
	{
		result = [NSDictionary dictionaryWithObjectsAndKeys:
				[NSNumber numberWithBool:YES], @"success",
				currentUpload, @"destinationPath",
				nil];
	}
	else if(overwrite)
	{
		NSError* error = nil;
		if(![fm removeItemAtPath:currentUpload error:&error])
		{
			NSString* reason = [error localizedFailureReason];
			if(reason==nil)
				reason = NSLocalizedString(@"Unknown Error",@"");
			result = [NSDictionary dictionaryWithObjectsAndKeys:
				[NSNumber numberWithBool:NO], @"success",
				@"error", @"reason",
				reason, @"message",
				nil];
		}
		else
		{
			result = [NSDictionary dictionaryWithObjectsAndKeys:
				[NSNumber numberWithBool:YES], @"success",
				currentUpload, @"destinationPath",
				nil];
		}
	}
	else
	{
		result = [NSDictionary dictionaryWithObjectsAndKeys:
			[NSNumber numberWithBool:NO], @"success",
			@"doublette", @"reason",
			nil];
	}
	return result;
}

- (void)iMBiPhoneViewServerReceiveFileFromComputerSuccess
{
	[self refreshFileNameCache];
	[currentUpload release];
	currentUpload=nil;
}

- (void)iMBiPhoneViewServerSendFileToComputerSuccess;
{
}

- (void)iMBiPhoneViewServerSendDataToComputerSuccess;
{
}
@end
